(function () {
    let data = null,
        obImg = null,
        obLoad = null,
        num = 0;
    const fallsBox = document.querySelector('#fallsBox'),
        columns = Array.from(fallsBox.querySelectorAll('.column')),
        loadMoreBox = document.querySelector('.loadMoreBox');

    /* 图片懒加载 */
    const lazyImg = function lazyImg(picBox) {
        let imgBox = picBox.querySelector('img'),
            trueImg = imgBox.getAttribute('data-image'),
            tempImg = new Image;
        tempImg.src = trueImg;
        tempImg.onload = () => {
            imgBox.src = trueImg;
            imgBox.style.opacity = 1;
        };
    };
    obImg = new IntersectionObserver(changes => {
        changes.forEach(item => {
            let { isIntersecting, target } = item;
            if (isIntersecting) {
                lazyImg(target);
                obImg.unobserve(target);
            }
        });
    }, { threshold: [0.5] });

    /* 基于ajax请求，从服务器获取数据 */
    const queryData = function queryData() {
        let xhr = new XMLHttpRequest;
        xhr.open('GET', './data.json', false);
        xhr.onreadystatechange = () => {
            let { readyState, status, responseText } = xhr;
            if (readyState === 4 && status === 200) {
                data = JSON.parse(responseText);
            }
        };
        xhr.send();
    };
    queryData();

    /* 数据绑定「瀑布流的效果」 */
    const render = function render() {
        // 按照渲染的宽度(230px)动态调整数据中的高度
        data = data.map(item => {
            let { width, height } = item;
            item.width = 230;
            item.height = Math.round(230 / (width / height));
            return item;
        });

        // 每三个为一组进行循环，每次取出三条数据
        for (let i = 0; i < data.length; i += 3) {
            let group = data.slice(i, i + 3);

            // 从第二轮循环开始，依次对数据和列进行排序
            if (i > 0) {
                group.sort((a, b) => a.height - b.height);
                columns.sort((a, b) => b.offsetHeight - a.offsetHeight);
            }

            // 循环三条数据：创建对应的三项内容，然后依次插入到三列中即可
            group.forEach((item, index) => {
                let { pic, title, height, link } = item;
                const term = document.createElement('div');
                term.className = "item";
                term.innerHTML = `<a href="${link}" target="_blank">
                    <div class="pic-box" style="height: ${height}px;">
                        <img src="" data-image="${pic}" alt="">
                    </div>
                    <p class="desc-box">${title}</p>
                </a>`;
                columns[index].appendChild(term);
                // 每插入一项，就把其内部的pic-box放在监听器中监听
                obImg.observe(term.querySelector('.pic-box'));
            });
        }
    };
    render();

    /* 触底加载更多数据 */
    loadMoreBox.style.display = 'block';
    obLoad = new IntersectionObserver(([item]) => {
        if (item.isIntersecting) {
            // 触底了:加载更多数据
            queryData();
            render();
            num++;
            if (num >= 3) {
                // 全部加载完毕
                loadMoreBox.innerHTML = `-- 已经全部加载完毕啦~~ --`;
                obLoad.unobserve(loadMoreBox);
            }
        }
    });
    obLoad.observe(loadMoreBox);
})();